import 'dart:async';
import 'package:audioplayers/audioplayers.dart';

import '../../common/ui/val_fast_string_tool.dart';

typedef AnimationBeginListener = void Function();
typedef AnimationEndListener = void Function();

class ValAudioPlayer {
  ValAudioPlayer._internal();

  static final ValAudioPlayer _instance = ValAudioPlayer._internal();

  factory ValAudioPlayer() => _instance;
  AudioPlayer? _audioPlayer;
  late StreamSubscription<void> _playerStateChangedSubscription;

  PlayerState get state => _audioPlayer?.state ?? PlayerState.stopped;

  String? messageId;

  void init() {
    _audioPlayer ??= AudioPlayer()..setReleaseMode(ReleaseMode.stop);
    _playerStateChangedSubscription = _audioPlayer!.onPlayerComplete.listen((state) {
      animationStopListeners[messageId]?.call();
    });
  }

  void play(String messageId, String path) {
    if (ValFastStringTool.equals(messageId, this.messageId)) {
      if (isPlaying()) {
        pause();
        animationStopListeners[messageId]?.call();
      } else if (isPaused()) {
        resume();
        animationStartListeners[messageId]?.call();
      } else {
        _audioPlayer?.play(DeviceFileSource(path));
        animationStartListeners[messageId]?.call();
      }
    } else {
      if (isPlaying()) {
        stop();
      }
      _audioPlayer?.play(DeviceFileSource(path));
      animationStartListeners[messageId]?.call();
      this.messageId = messageId;
    }
  }

  void playUrl(String messageId, String url) {
    if (ValFastStringTool.equals(messageId, this.messageId)) {
      if (isPlaying()) {
        pause();
        animationStopListeners[messageId]?.call();
      } else if (isPaused()) {
        resume();
        animationStartListeners[messageId]?.call();
      } else {
        _audioPlayer?.play(UrlSource(url));
        animationStartListeners[messageId]?.call();
      }
    } else {
      if (isPlaying()) {
        stop();
      }
      _audioPlayer?.play(UrlSource(url));
      animationStartListeners[messageId]?.call();
      this.messageId = messageId;
    }
  }

  void pause() => _audioPlayer?.pause();

  void resume() => _audioPlayer?.resume();

  void stop() {
    _audioPlayer?.stop();
    animationStopListeners[messageId]?.call();
  }

  bool isPlaying() => state == PlayerState.playing;

  bool isPaused() => state == PlayerState.paused;

  void dispose() {
    _audioPlayer?.stop();
    messageId = '';
    animationStartListeners.clear();
    animationStopListeners.clear();
    _playerStateChangedSubscription.cancel();
  }

  Map<String, AnimationBeginListener> animationStartListeners = <String, AnimationBeginListener>{};

  Map<String, AnimationEndListener> animationStopListeners = <String, AnimationEndListener>{};

  void addAnimationStartListener(String messageId, AnimationBeginListener listener) =>
      animationStartListeners[messageId] = listener;

  void addAnimationStopListener(String messageId, AnimationEndListener listener) =>
      animationStopListeners[messageId] = listener;

  void removeAnimationListener(String messageId) {
    animationStartListeners.remove(messageId);
    animationStopListeners.remove(messageId);
  }
}


